home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 2002 #12 / Amiga Plus CD - 2002 - No. 12.iso / Tools / Freeware / Swf_Player / Lib / shape.cc < prev    next >
Encoding:
C/C++ Source or Header  |  2002-11-17  |  30.8 KB  |  1,206 lines

  1. /////////////////////////////////////////////////////////////
  2. // Flash Plugin and Player
  3. // Copyright (C) 1998,1999 Olivier Debon
  4. // 
  5. // This program is free software; you can redistribute it and/or
  6. // modify it under the terms of the GNU General Public License
  7. // as published by the Free Software Foundation; either version 2
  8. // of the License, or (at your option) any later version.
  9. // 
  10. // This program is distributed in the hope that it will be useful,
  11. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. // GNU General Public License for more details.
  14. // 
  15. // You should have received a copy of the GNU General Public License
  16. // along with this program; if not, write to the Free Software
  17. // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  18. // 
  19. ///////////////////////////////////////////////////////////////
  20. //  Author : Olivier Debon  <odebon@club-internet.fr>
  21. //
  22.  
  23. #include "swf.h"
  24.  
  25. #ifdef RCSID
  26. static char *rcsid = "$Id: shape.cc,v 1.5 1999/09/10 13:08:52 ode Exp $";
  27. #endif
  28.  
  29. #define PRINT 0
  30.  
  31. #define ABS(v) ((v) < 0 ? -(v) : (v))
  32.  
  33. static void prepareStyles(GraphicDevice *gd, Matrix *matrix, Cxform *cxform, FillStyleDef *f, long n);
  34.  
  35. static void clearStyles(GraphicDevice *gd, FillStyleDef *f, long n);
  36.  
  37. static void drawShape(GraphicDevice *gd, Matrix *matrix1, Cxform *cxform, Shape *shape,
  38.                       ShapeAction shapeAction, void *id,ScanLineFunc scan_line_func);
  39.  
  40. // Constructor
  41.  
  42. Shape::Shape(long id, int level) : Character(ShapeType, id)
  43. {
  44.     defLevel = level;
  45.  
  46.     defaultFillStyle.type = f_Solid;
  47.     defaultFillStyle.color.red = 0;
  48.     defaultFillStyle.color.green = 0;
  49.     defaultFillStyle.color.blue = 0;
  50.     defaultFillStyle.color.alpha = ALPHA_OPAQUE;
  51.  
  52.     defaultLineStyle.width = 0;
  53.  
  54.     // This is to force a first update
  55.     lastMat.a = 0;
  56.     lastMat.d = 0;
  57.     shape_size += sizeof(Shape);
  58.     shape_nb ++;
  59.  
  60.     file_ptr = NULL;
  61.     getStyles = 0;
  62.     getAlpha = 0;
  63. }
  64.  
  65. Shape::~Shape()
  66. {
  67.     if (file_ptr) {
  68.         free(file_ptr);
  69.     }
  70. }
  71.  
  72. void
  73. Shape::setBoundingBox(Rect rect)
  74. {
  75.     boundary = rect;
  76. }
  77.  
  78. void
  79. Shape::getBoundingBox(Rect *bb, DisplayListEntry *e)
  80. {
  81.     *bb =  boundary;
  82. }
  83.  
  84. int
  85. Shape::execute(GraphicDevice *gd, Matrix *matrix, Cxform *cxform)
  86. {
  87.     //printf("TagId = %d\n", getTagId());
  88.     //if (getTagId() != 220) return 0;
  89.  
  90.     if (cxform) {
  91.         defaultFillStyle.color = cxform->getColor(gd->getForegroundColor());
  92.     } else {
  93.         defaultFillStyle.color = gd->getForegroundColor();
  94.     }
  95.     defaultFillStyle.color.pixel = gd->allocColor(defaultFillStyle.color);
  96.  
  97.     drawShape(gd, matrix, cxform, this, ShapeDraw, NULL, 0);
  98.     return 0;
  99. }
  100.  
  101. void
  102. Shape::getRegion(GraphicDevice *gd, Matrix *matrix, void *id, ScanLineFunc scan_line_func)
  103. {
  104.     gd->setClipping(0);
  105.     drawShape(gd,matrix,0,this,ShapeGetRegion,id,scan_line_func);
  106.     gd->setClipping(1);
  107. }
  108.  
  109. /************************************************************************/
  110.  
  111. /* create a new path */
  112.  
  113. static void newPath(ShapeParser *shape,
  114.                     long x, long y)
  115. {
  116.     Path *p;
  117.     long x1,y1;
  118.  
  119.     p=&shape->curPath;
  120.     
  121.     x1 = shape->matrix->getX(x, y);
  122.     y1 = shape->matrix->getY(x, y);
  123.  
  124.     p->lastX = x1;
  125.     p->lastY = y1;
  126.  
  127.     p->nb_edges = 0;
  128.     p->nb_segments = 0;
  129. }
  130.  
  131.  
  132. static void addSegment1(ShapeParser *shape,
  133.                         long x, long y,
  134.                         FillStyleDef *f0,
  135.                         FillStyleDef *f1,
  136.                         LineStyleDef *l)
  137. {
  138.     Path *p;
  139.     p=&shape->curPath;
  140.  
  141.     if (l) {
  142.         /* a line is defined ... it will be drawn later */
  143.         LineSegment *ls;
  144.  
  145.         ls = new LineSegment;
  146.     if (ls != NULL) {
  147.         ls->l = l;
  148.         ls->x1 = p->lastX;
  149.         ls->y1 = p->lastY;
  150.         ls->x2 = x;
  151.         ls->y2 = y;
  152.         ls->first = (p->nb_segments == 0);
  153.         ls->next = NULL;
  154.         if (shape->last_line == NULL) {
  155.             shape->first_line = ls;
  156.         } else {
  157.             shape->last_line->next = ls;
  158.         }
  159.         shape->last_line = ls;
  160.     }
  161.     }
  162.  
  163.     /* anti antialiasing not needed if line */
  164.     if (!shape->reverse) {
  165.         shape->gd->addSegment(p->lastX,p->lastY,x,y,f0,f1,l ? 0 : 1);
  166.     } else {
  167.         shape->gd->addSegment(p->lastX,p->lastY,x,y,f1,f0,l ? 0 : 1);
  168.     }
  169.  
  170.     p->lastX = x;
  171.     p->lastY = y;
  172.  
  173.     p->nb_segments++;
  174. }
  175.  
  176.  
  177. static void addLine(ShapeParser *shape, long x, long y,
  178.                     FillStyleDef *f0,
  179.                     FillStyleDef *f1,
  180.                     LineStyleDef *l)
  181. {
  182.     long x1,y1;
  183.     Path *p;
  184.  
  185.     p=&shape->curPath;
  186.  
  187.     x1 = shape->matrix->getX(x, y);
  188.     y1 = shape->matrix->getY(x, y);
  189.     
  190.     addSegment1(shape,x1,y1,f0,f1,l);
  191.  
  192.     p->nb_edges++;
  193. }
  194.  
  195.  
  196. // This is based on Divide and Conquer algorithm.
  197.  
  198. #define BFRAC_BITS  0
  199. #define BFRAC       (1 << BFRAC_BITS)
  200.  
  201. static void
  202. bezierBuildPoints (ShapeParser *s,
  203.                    int subdivisions,
  204.                    long a1X, long a1Y,
  205.                    long cX, long cY,
  206.                    long a2X, long a2Y)
  207. {
  208.     long c1X,c1Y;
  209.     long c2X,c2Y;
  210.     long X,Y;
  211.     long xmin,ymin,xmax,ymax;
  212.  
  213.     if (subdivisions != 0) {
  214.  
  215.         /* find the bounding box */
  216.  
  217.         if (a1X < cX) {
  218.             xmin = a1X;
  219.             xmax = cX;
  220.         } else {
  221.             xmin = cX;
  222.             xmax = a1X;
  223.         }
  224.         if (a2X < xmin) xmin = a2X;
  225.         if (a2X > xmax) xmax = a2X;
  226.         
  227.         if (a1Y < cY) {
  228.             ymin = a1Y;
  229.             ymax = cY;
  230.         } else {
  231.             ymin = cY;
  232.             ymax = a1Y;
  233.         }
  234.         if (a2Y < ymin) ymin = a2Y;
  235.         if (a2Y > ymax) ymax = a2Y;
  236.     
  237.         if (((xmax - xmin) + (ymax - ymin)) >= (BFRAC*FRAC*2)) {
  238.             // Control point 1
  239.             c1X = (a1X+cX) >> 1;
  240.             c1Y = (a1Y+cY) >> 1;
  241.             
  242.             // Control point 2
  243.             c2X = (a2X+cX) >> 1;
  244.             c2Y = (a2Y+cY) >> 1;
  245.             
  246.             // New point
  247.             X = (c1X+c2X) >> 1;
  248.             Y = (c1Y+c2Y) >> 1;
  249.             
  250.             subdivisions--;
  251.  
  252.             bezierBuildPoints(s, subdivisions, 
  253.                               a1X, a1Y, c1X, c1Y, X, Y);
  254.             bezierBuildPoints(s, subdivisions, 
  255.                               X, Y, c2X, c2Y, a2X, a2Y);
  256.             
  257.             return;
  258.         }
  259.     }
  260.             
  261.     addSegment1(s, (a2X+(BFRAC/2)) >> BFRAC_BITS, 
  262.                 (a2Y+(BFRAC/2)) >> BFRAC_BITS, s->f0, s->f1, s->l);
  263. }
  264.  
  265. /* this code is broken, but useful to get something */
  266. static void flushPaths(ShapeParser *s)
  267. {
  268.     LineSegment *ls;
  269.     LineStyleDef *l;
  270.     long nx,ny,nn,w;
  271.     GraphicDevice *gd = s->gd;
  272.  
  273.     /* draw the filled polygon */
  274.     gd->drawPolygon();
  275.     
  276.     /* draw the lines */
  277.     ls = s->first_line;
  278.     if (ls != NULL) {
  279.         do {
  280.             l = ls->l;
  281.  
  282. #if 0
  283.             printf("line %d %d %d %d width=%d\n",
  284.                    ls->x1, ls->y1, ls->x2, ls->y2, l->width);
  285. #endif
  286.  
  287.             /* XXX: this width is false, but it is difficult (and expensive)
  288.                to have the correct one */
  289.             w = ABS((long)(s->matrix->a * l->width));
  290.  
  291.             if (w <= ((3*FRAC)/2)) {
  292.             w = FRAC;
  293.         }
  294. #ifdef THIN_LINES
  295.             if (w <= ((3*FRAC)/2)) {
  296.                 // draw the thin lines only in shapeAction == shapeDraw
  297.                 if (gd->scan_line_func == NULL) {
  298.                     gd->setForegroundColor(l->fillstyle.color);
  299.                     gd->drawLine(ls->x1, ls->y1, ls->x2, ls->y2, w);
  300.                 }
  301.             } else {
  302. #else
  303.         {
  304. #endif
  305.                 /* compute the normal vector */
  306.                 
  307.                 nx = -(ls->y2 - ls->y1);
  308.                 ny = (ls->x2 - ls->x1);
  309.                 
  310.                 /* normalize & width */
  311.                 nn = 2 * (long) sqrt(nx * nx + ny * ny);
  312.                 
  313. #define UL ls->x1 + nx -ny, ls->y1 + ny +nx
  314. #define UR ls->x2 + nx +ny, ls->y2 + ny -nx
  315. #define LL ls->x1 - nx -ny, ls->y1 - ny +nx
  316. #define LR ls->x2 - nx +ny, ls->y2 - ny -nx
  317.  
  318.                 if (nn > 0) {
  319.                     nx = (nx * w) / nn;
  320.                     ny = (ny * w) / nn;
  321.                     
  322.                     /* top segment */
  323.                     gd->addSegment(UL, UR, NULL, &l->fillstyle, 1);
  324.                     
  325.                     /* bottom segment */
  326.                     gd->addSegment(LL, LR, &l->fillstyle, NULL, 1);
  327.                 
  328.                     /* right segment */
  329.                     gd->addSegment(UR, LR, &l->fillstyle, NULL, 1);
  330.                 
  331.                     /* left segment */
  332.                     gd->addSegment(UL, LL, NULL, &l->fillstyle, 1);
  333.                 
  334.                     /* draw the line polygon */
  335.                     gd->drawPolygon();
  336.                 }
  337.             }
  338.                 
  339.             ls = ls->next;
  340.         } while (ls != NULL);
  341.         
  342.         /* delete the line structures */
  343.  
  344.         ls = s->first_line;
  345.         while (ls != NULL) {
  346.             LineSegment *ls1;
  347.             ls1 = ls->next;
  348.             delete ls;
  349.             ls = ls1;
  350.         }
  351.  
  352.         /* reset the line pointers */
  353.         s->first_line = NULL;
  354.         s->last_line = NULL;
  355.     }
  356. }
  357.  
  358.  
  359. static void addBezier(ShapeParser *shape, 
  360.                       long ctrlX1, long ctrlY1,
  361.                       long newX1, long newY1,
  362.                       FillStyleDef *f0,
  363.                       FillStyleDef *f1,
  364.                       LineStyleDef *l)
  365. {
  366.     long newX,newY,ctrlX,ctrlY;
  367.     Path *p;
  368.  
  369.     p=&shape->curPath;
  370.  
  371.     /* note: we do the matrix multiplication before calculating the
  372.        bezier points (faster !) */
  373.  
  374.     ctrlX = shape->matrix->getX(ctrlX1, ctrlY1);
  375.     ctrlY = shape->matrix->getY(ctrlX1, ctrlY1);
  376.     newX = shape->matrix->getX(newX1, newY1);
  377.     newY = shape->matrix->getY(newX1, newY1);
  378.  
  379.     shape->f0 = f0;
  380.     shape->f1 = f1;
  381.     shape->l = l;
  382.  
  383.     bezierBuildPoints(shape, 3,
  384.                       p->lastX<<BFRAC_BITS,p->lastY<<BFRAC_BITS,
  385.                       ctrlX<<BFRAC_BITS,ctrlY<<BFRAC_BITS,
  386.                       newX<<BFRAC_BITS,newY<<BFRAC_BITS);
  387.  
  388.     p->nb_edges++;
  389. }
  390.  
  391. /***********************************************************************/
  392.  
  393.  
  394. /* bit parser */
  395.  
  396. static void InitBitParser(struct BitParser *b,U8 *buf) 
  397. {
  398.     b->ptr = buf;
  399. }
  400.  
  401. static void InitBits(struct BitParser *b)
  402. {
  403.     // Reset the bit position and buffer.
  404.     b->m_bitPos = 0;
  405.     b->m_bitBuf = 0;
  406. }
  407.  
  408.  
  409.  
  410. static inline U8 GetByte(struct BitParser *b)
  411. {
  412.     U8 v;
  413.     v = *b->ptr++;
  414.     return v;
  415. }
  416.  
  417. static inline U16 GetWord(struct BitParser *b)
  418. {
  419.     U8 *s;
  420.     U16 v;
  421.     s = b->ptr;
  422.     v = s[0] | ((U16) s[1] << 8);
  423.     b->ptr = s + 2;
  424.     return v;
  425. }
  426.  
  427. static inline U32 GetDWord(struct BitParser *b)
  428. {
  429.     U32 v;
  430.     U8 * s = b->ptr;
  431.     v = (U32) s[0] | ((U32) s[1] << 8) | 
  432.         ((U32) s[2] << 16) | ((U32) s [3] << 24);
  433.     b->ptr = s + 4;
  434.     return v;
  435. }
  436.  
  437. static inline U32 GetBit (struct BitParser *b)
  438. {
  439.     U32 v;
  440.     S32 m_bitPos = b->m_bitPos;
  441.     U32 m_bitBuf = b->m_bitBuf;
  442.     
  443.     if (m_bitPos == 0) {
  444.         m_bitBuf = (U32)(*b->ptr++) << 24;
  445.         m_bitPos = 8;
  446.     }
  447.  
  448.     v = (m_bitBuf >> 31);
  449.  
  450.     m_bitPos--;
  451.     m_bitBuf <<= 1;
  452.  
  453.     b->m_bitPos = m_bitPos;
  454.     b->m_bitBuf = m_bitBuf;
  455.  
  456.     return v;
  457. }
  458.  
  459. static inline U32 GetBits (struct BitParser *b, int n)
  460. {
  461.     U32 v;
  462.     S32 m_bitPos = b->m_bitPos;
  463.     U32 m_bitBuf = b->m_bitBuf;
  464.  
  465.     if (n == 0) 
  466.         return 0;
  467.  
  468.     while (m_bitPos < n) {
  469.         m_bitBuf |= (U32)(*b->ptr++) << (24 - m_bitPos);
  470.         m_bitPos += 8;
  471.     }
  472.  
  473.     v = m_bitBuf >> (32 - n);
  474.     m_bitBuf <<= n;
  475.     m_bitPos -= n;
  476.  
  477.     b->m_bitPos = m_bitPos;
  478.     b->m_bitBuf = m_bitBuf;
  479.     return v;
  480. }
  481.  
  482. // Get n bits from the string with sign extension.
  483. static inline S32 GetSBits (struct BitParser *b,S32 n)
  484. {
  485.     // Get the number as an unsigned value.
  486.     S32 v = (S32) GetBits(b,n);
  487.  
  488.     // Is the number negative?
  489.     if (v & (1L << (n - 1)))
  490.     {
  491.         // Yes. Extend the sign.
  492.         v |= -1L << n;
  493.     }
  494.  
  495.     return v;
  496. }
  497.  
  498.  
  499.  
  500. /************************************************************************/
  501.  
  502. static void GetMatrix(BitParser *b, Matrix* mat)
  503. {
  504.     InitBits(b);
  505.  
  506.     // Scale terms
  507.     if (GetBit(b))
  508.     {
  509.         int nBits = (int) GetBits(b,5);
  510.         mat->a = (float)(GetSBits(b,nBits))/(float)0x10000;
  511.         mat->d = (float)(GetSBits(b,nBits))/(float)0x10000;
  512.     }
  513.     else
  514.     {
  515.          mat->a = mat->d = 1.0;
  516.     }
  517.  
  518.     // Rotate/skew terms
  519.     if (GetBit(b))
  520.     {
  521.         int nBits = (int)GetBits(b,5);
  522.         mat->c = (float)(GetSBits(b,nBits))/(float)0x10000;
  523.         mat->b = (float)(GetSBits(b,nBits))/(float)0x10000;
  524.     }
  525.     else
  526.     {
  527.          mat->b = mat->c = 0.0;
  528.     }
  529.  
  530.     // Translate terms
  531.     int nBits = (int) GetBits(b,5);
  532.     mat->tx = GetSBits(b,nBits);
  533.     mat->ty = GetSBits(b,nBits);
  534. }
  535.  
  536. static FillStyleDef * ParseFillStyle(ShapeParser *shape, long *n, long getAlpha)
  537. {
  538.     BitParser *b = &shape->bit_parser;
  539.     FillStyleDef *defs;
  540.     U16 i = 0;
  541.  
  542.     // Get the number of fills.
  543.     U16 nFills = GetByte(b);
  544.  
  545.     // Do we have a larger number?
  546.     if (nFills == 255)
  547.     {
  548.         // Get the larger number.
  549.         nFills = GetWord(b);
  550.     }
  551.  
  552.     *n = nFills;
  553.     defs = new FillStyleDef[ nFills ];
  554.     if (defs == NULL) return NULL;
  555.  
  556.     // Get each of the fill style.
  557.     for (i = 0; i < nFills; i++)
  558.     {
  559.         U16 fillStyle = GetByte(b);
  560.  
  561.         defs[i].type = (FillType) fillStyle;
  562.  
  563.         if (fillStyle & 0x10)
  564.         {
  565.             defs[i].type = (FillType) (fillStyle & 0x12);
  566.  
  567.             // Get the gradient matrix.
  568.             GetMatrix(b,&(defs[i].matrix));
  569.  
  570.             // Get the number of colors.
  571.             defs[i].gradient.nbGradients = GetByte(b);
  572.  
  573.             // Get each of the colors.
  574.             for (U16 j = 0; j < defs[i].gradient.nbGradients; j++)
  575.             {
  576.                 defs[i].gradient.ratio[j] = GetByte(b);
  577.                 defs[i].gradient.color[j].red = GetByte(b);
  578.                 defs[i].gradient.color[j].green = GetByte(b);
  579.                 defs[i].gradient.color[j].blue = GetByte(b);
  580.                 if (getAlpha) {
  581.                                     defs[i].gradient.color[j].alpha = GetByte(b);
  582.                 } else {
  583.                     defs[i].gradient.color[j].alpha = ALPHA_OPAQUE;
  584.                                 }
  585.             }
  586.         }
  587.         else if (fillStyle & 0x40)
  588.         {
  589.             defs[i].type = (FillType) (fillStyle & 0x41);
  590.  
  591.             // Get the bitmapId
  592.             defs[i].bitmap = (Bitmap *)shape->dict->getCharacter(GetWord(b));
  593.             // Get the bitmap matrix.
  594.             GetMatrix(b,&(defs[i].matrix));
  595.         }
  596.         else
  597.         {
  598.             defs[i].type = (FillType) 0;
  599.  
  600.             // A solid color
  601.             defs[i].color.red = GetByte(b);
  602.             defs[i].color.green = GetByte(b);
  603.             defs[i].color.blue = GetByte(b);
  604.             if (getAlpha) {
  605.                 defs[i].color.alpha = GetByte(b);
  606.             } else {
  607.                 defs[i].color.alpha = ALPHA_OPAQUE;
  608.                         }
  609.         }
  610.     }
  611.     
  612.     return defs;
  613. }
  614.  
  615. static LineStyleDef * ParseLineStyle(ShapeParser *shape, long *n, long getAlpha)
  616. {
  617.     BitParser *b = &shape->bit_parser;
  618.     LineStyleDef *defs,*def;
  619.     FillStyleDef *f;
  620.     long i;
  621.  
  622.     // Get the number of lines.
  623.     U16 nLines = GetByte(b);
  624.  
  625.     // Do we have a larger number?
  626.     if (nLines == 255)
  627.     {
  628.         // Get the larger number.
  629.         nLines = GetWord(b);
  630.     }
  631.  
  632.     *n = nLines;
  633.     defs = new LineStyleDef[ nLines ];
  634.     if (defs == NULL) return NULL;
  635.  
  636.     // Get each of the line styles.
  637.     for (i = 0; i < nLines; i++)
  638.     {
  639.             def=&defs[i];
  640.             def->width = GetWord(b);
  641.             def->color.red = GetByte(b);
  642.             def->color.green = GetByte(b);
  643.             def->color.blue = GetByte(b);
  644.             if (getAlpha) {
  645.                 def->color.alpha = GetByte(b);
  646.             } else {
  647.                 def->color.alpha = ALPHA_OPAQUE;
  648.             }
  649.             
  650.             f=&def->fillstyle;
  651.             f->type = f_Solid;
  652.             f->color = def->color;
  653.             if (shape->cxform) {
  654.                 f->color = shape->cxform->getColor(f->color);
  655.             }
  656.             f->color.pixel = shape->gd->allocColor(f->color);
  657.     }
  658.  
  659.     return defs;
  660. }
  661.  
  662. /* 0 = end of shape */
  663. static int ParseShapeRecord(ShapeParser *shape, ShapeRecord *sr, long getAlpha)
  664. {
  665.     BitParser *b = &shape->bit_parser;
  666.  
  667.     // Determine if this is an edge.
  668.     BOOL isEdge = (BOOL) GetBit(b);
  669.  
  670.     if (!isEdge)
  671.     {
  672.         // Handle a state change
  673.         U16 flags = (U16) GetBits(b,5);
  674.  
  675.         // Are we at the end?
  676.         if (flags == 0)
  677.         {
  678.             // End of shape
  679.             return 0;
  680.         }
  681.  
  682.         sr->type = shapeNonEdge;
  683.         sr->flags = (ShapeFlags)flags;
  684.  
  685.         // Process a move to.
  686.         if (flags & flagsMoveTo)
  687.         {
  688.             U16 nBits = (U16) GetBits(b,5);
  689.             sr->x = GetSBits(b,nBits);
  690.             sr->y = GetSBits(b,nBits);
  691.         }
  692.  
  693.         // Get new fill info.
  694.         if (flags & flagsFill0)
  695.         {
  696.             sr->fillStyle0 = GetBits(b,shape->m_nFillBits);
  697.         }
  698.         if (flags & flagsFill1)
  699.         {
  700.             sr->fillStyle1 = GetBits(b,shape->m_nFillBits);
  701.         }
  702.  
  703.         // Get new line info
  704.         if (flags & flagsLine)
  705.         {
  706.             sr->lineStyle = GetBits(b,shape->m_nLineBits);
  707.         }
  708.  
  709.         // Check to get a new set of styles for a new shape layer.
  710.         if (flags & flagsNewStyles)
  711.         {
  712.             FillStyleDef *fillDefs;
  713.             LineStyleDef *lineDefs;
  714.             long n;
  715.  
  716.             // Parse the style.
  717.             fillDefs = ParseFillStyle(shape, &n, getAlpha);
  718.             if (fillDefs == NULL)  return 0;
  719.  
  720.             sr->newFillStyles = fillDefs;
  721.             sr->nbNewFillStyles = n;
  722.  
  723.             lineDefs = ParseLineStyle(shape, &n, getAlpha);
  724.             if (lineDefs == NULL) return 0;
  725.  
  726.             sr->newLineStyles = lineDefs;
  727.             sr->nbNewLineStyles = n;
  728.  
  729.             InitBits(b);    // Bug !
  730.  
  731.             // Reset.
  732.             shape->m_nFillBits = (U16) GetBits(b,4);
  733.             shape->m_nLineBits = (U16) GetBits(b,4);
  734.         }
  735.  
  736.         //if (flags & flagsEndShape)
  737.             //printf("\tEnd of shape.\n\n");
  738.   
  739.         return flags & flagsEndShape ? 0 : 1;
  740.     }
  741.     else
  742.     {
  743.         if (GetBit(b))
  744.         {
  745.             sr->type = shapeLine;
  746.  
  747.             // Handle a line
  748.             U16 nBits = (U16) GetBits(b,4) + 2;    // nBits is biased by 2
  749.  
  750.             // Save the deltas
  751.             if (GetBit(b))
  752.             {
  753.                 // Handle a general line.
  754.                 sr->dX = GetSBits(b,nBits);
  755.                 sr->dY = GetSBits(b,nBits);
  756.             }
  757.             else
  758.             {
  759.                 // Handle a vert or horiz line.
  760.                 if (GetBit(b))
  761.                 {
  762.                     // Vertical line
  763.                     sr->dY = GetSBits(b,nBits);
  764.                     sr->dX = 0;
  765.                 }
  766.                 else
  767.                 {
  768.                     // Horizontal line
  769.                     sr->dX = GetSBits(b,nBits);
  770.                     sr->dY = 0;
  771.                 }
  772.             }
  773.         }
  774.         else
  775.         {
  776.             sr->type = shapeCurve;
  777.  
  778.              // Handle a curve
  779.             U16 nBits = (U16) GetBits(b,4) + 2;    // nBits is biased by 2
  780.  
  781.             // Get the control
  782.             sr->ctrlX = GetSBits(b,nBits);
  783.             sr->ctrlY = GetSBits(b,nBits);
  784.  
  785.             // Get the anchor
  786.             sr->anchorX = GetSBits(b,nBits);
  787.             sr->anchorY = GetSBits(b,nBits);
  788.         }
  789.  
  790.         return 1;
  791.     }
  792. }
  793.  
  794. static void drawShape(GraphicDevice *gd, Matrix *matrix1, Cxform *cxform, Shape *shape,
  795.                       ShapeAction shapeAction, void *id,ScanLineFunc scan_line_func)
  796. {
  797.     LineStyleDef *l;
  798.     FillStyleDef *f0;
  799.     FillStyleDef *f1;
  800.     ShapeRecord sr1,*sr = &sr1;
  801.     int firstPoint;
  802.     long lastX,lastY;
  803.     LineStyleDef *curLineStyle;
  804.     long curNbLineStyles;
  805.     FillStyleDef *curFillStyle;
  806.     long curNbFillStyles;
  807.     StyleList *sl;
  808.     ShapeParser sp1,*sp=&sp1;
  809.     BitParser *b;
  810.     Matrix     mat,*matrix;
  811.  
  812.     mat = (*gd->adjust) * (*matrix1);
  813.     matrix = &mat;
  814.     
  815.     sp->reverse = (mat.a * mat.d) < 0;
  816.  
  817.     curLineStyle = NULL;
  818.     curNbLineStyles = 0;
  819.     curFillStyle = NULL;
  820.     curNbFillStyles = 0;
  821.     sp->style_list = NULL;
  822.  
  823.     sp->shape = shape;
  824.     sp->gd = gd;
  825.     sp->matrix = matrix;
  826.     sp->cxform = cxform;
  827.     sp->dict = shape->dict;
  828.  
  829.     if (shapeAction == ShapeGetRegion) {
  830.         gd->scan_line_func = scan_line_func;
  831.         gd->scan_line_func_id = id;
  832.     } else {
  833.         gd->scan_line_func = NULL;
  834.     }
  835.  
  836.     b = &sp->bit_parser;
  837.     InitBitParser(b,shape->file_ptr);
  838.  
  839.     if (shape->getStyles) {
  840.         // ShapeWithStyle
  841.         curFillStyle = ParseFillStyle(sp, &curNbFillStyles, shape->getAlpha);
  842.     if (curFillStyle == NULL) return;
  843.  
  844.         curLineStyle = ParseLineStyle(sp, &curNbLineStyles, shape->getAlpha);
  845.     if (curLineStyle == NULL) return;
  846.  
  847.         sl = new StyleList;
  848.     if (sl == NULL) return;
  849.  
  850.         sl->next = NULL;
  851.         sl->newFillStyles = curFillStyle;
  852.         sl->nbNewFillStyles = curNbFillStyles;
  853.         sl->newLineStyles = curLineStyle;
  854.         sl->nbNewLineStyles = curNbLineStyles;
  855.  
  856.         sp->style_list = sl;
  857.  
  858.         if (shapeAction == ShapeDraw) {
  859.             prepareStyles(gd, matrix, cxform, curFillStyle, curNbFillStyles);
  860.         }
  861.     }
  862.         
  863.     InitBits(b);
  864.     sp->m_nFillBits = (U16) GetBits(b,4);
  865.     sp->m_nLineBits = (U16) GetBits(b,4);
  866.  
  867.     l = 0;
  868.     f0 = 0;
  869.     f1 = 0;
  870.     firstPoint = 1;
  871.     lastX = 0;
  872.     lastY = 0;
  873.     sp->curPath.nb_edges = 0;
  874.     sp->first_line = NULL;
  875.     sp->last_line = NULL;
  876.  
  877.     for(;;) {
  878.         if (ParseShapeRecord(sp, sr, shape->getAlpha) == 0) break;
  879.  
  880.         switch (sr->type)
  881.         {
  882.             case shapeNonEdge:
  883.                 if (sr->flags & flagsNewStyles) {
  884.  
  885.                     curFillStyle = sr->newFillStyles;
  886.                     curNbFillStyles = sr->nbNewFillStyles;
  887.                     curLineStyle = sr->newLineStyles;
  888.                     curNbLineStyles = sr->nbNewLineStyles;
  889.                     
  890.                     sl = new StyleList;
  891.                     sl->next = sp->style_list;
  892.                     sl->newFillStyles = sr->newFillStyles;
  893.                     sl->nbNewFillStyles = sr->nbNewFillStyles;
  894.                     sl->newLineStyles = sr->newLineStyles;
  895.                     sl->nbNewLineStyles = sr->nbNewLineStyles;
  896.  
  897.                     sp->style_list = sl;
  898.  
  899.                     if (shapeAction == ShapeDraw) {
  900.                         prepareStyles(gd, matrix, cxform, curFillStyle, curNbFillStyles);
  901.                     }
  902.                 }
  903.                 if (sr->flags & flagsFill0) {
  904.                     if (sr->fillStyle0) {
  905.                         if (curFillStyle) {
  906.                             f0 = &curFillStyle[sr->fillStyle0-1];
  907.                         } else {
  908.                             f0 = &shape->defaultFillStyle;
  909.                         }
  910.                     } else {
  911.                         f0 = 0;
  912.                     }
  913.                 }
  914.                 if (sr->flags & flagsFill1) {
  915.                     if (sr->fillStyle1) {
  916.                         if (curFillStyle) {
  917.                             f1 = &curFillStyle[sr->fillStyle1-1];
  918.                         } else {
  919.                             f1 = &shape->defaultFillStyle;
  920.                         }
  921.                     } else {
  922.                         f1 = 0;
  923.                     }
  924.                 }
  925.                 if (sr->flags & flagsLine) {
  926.                     if (sr->lineStyle) {
  927.                         l = &curLineStyle[sr->lineStyle-1];
  928.                     } else {
  929.                         l = 0;
  930.                     }
  931.                 }
  932.                 if (sr->flags & flagsMoveTo) {
  933.                     if (sp->curPath.nb_edges == 0) {
  934.                         /* if no edges, draw the polygon, then the lines */
  935.                         flushPaths(sp);
  936.                     }
  937.  
  938.                     newPath(sp, sr->x, sr->y);
  939.                     firstPoint = 0;
  940.  
  941.                     lastX = sr->x;
  942.                     lastY = sr->y;
  943.  
  944. #if PRINT
  945.                     printf("---------\nX,Y    = %4d,%4d\n", sr->x/20, sr->y/20);
  946. #endif
  947.                 }
  948.                 break;
  949.             case shapeCurve:
  950.                 // Handle Bezier Curves !!!
  951.                 if (firstPoint) {
  952.                     newPath(sp, 0, 0);
  953.                     firstPoint = 0;
  954.                 }
  955.                 {
  956.                     long newX,newY,ctrlX,ctrlY;
  957.                     
  958.                     ctrlX = lastX+sr->ctrlX;
  959.                     ctrlY = lastY+sr->ctrlY;
  960.                     newX = ctrlX+sr->anchorX;
  961.                     newY = ctrlY+sr->anchorY;
  962.  
  963. #if 1
  964.                     addBezier(sp, ctrlX, ctrlY, newX, newY, f0 , f1, l);
  965. #else
  966.                     addLine(sp, newX, newY, f0, f1, l);
  967. #endif
  968.                     
  969.                     lastX = newX;
  970.                     lastY = newY;
  971.                 }
  972.                 break;
  973.             case shapeLine:
  974.                 if (firstPoint) {
  975.                     newPath(sp, 0, 0);
  976.                     firstPoint = 0;
  977.                 }
  978.  
  979.                 lastX += sr->dX;
  980.                 lastY += sr->dY;
  981.  
  982.                 addLine(sp, lastX, lastY, f0, f1, l);
  983. #if PRINT
  984.                 printf(" X, Y  = %4d,%4d\n", lastX/20, lastY/20);
  985. #endif
  986.                 break;
  987.         }
  988.     }
  989.  
  990.     /* XXX: should test if there is something to draw */
  991.     flushPaths(sp);
  992.  
  993.     /* free the styles */
  994.     while (sp->style_list) {
  995.         StyleList *sl;
  996.         
  997.         sl=sp->style_list;
  998.         sp->style_list = sl->next;
  999.         
  1000.         if (shapeAction == ShapeDraw) {
  1001.             clearStyles(gd, sl->newFillStyles, sl->nbNewFillStyles);
  1002.         }
  1003.  
  1004.         delete[] sl->newFillStyles;
  1005.         delete[] sl->newLineStyles;
  1006.         
  1007.         delete sl;
  1008.     }
  1009. }
  1010.  
  1011. static void
  1012. prepareStyles(GraphicDevice *gd, Matrix *matrix, Cxform *cxform, 
  1013.               FillStyleDef *ftab, long n)
  1014. {
  1015.     long fs;
  1016.     FillStyleDef *f;
  1017.  
  1018.     for(fs = 0; fs < n; fs++)
  1019.     {
  1020.         f = ftab + fs;
  1021.         switch (f->type)
  1022.         {
  1023.             case f_None:
  1024.             break;
  1025.             case f_Solid:
  1026.                 if (cxform) {
  1027.                     f->color = cxform->getColor(f->color);
  1028.                 }
  1029.                 f->color.pixel = gd->allocColor(f->color);
  1030.                 break;
  1031.             case f_LinearGradient:
  1032.             case f_RadialGradient:
  1033.                 {
  1034.                     Matrix mat;
  1035.                     int  n,r,l;
  1036.                     long red, green, blue, alpha;
  1037.                     long dRed, dGreen, dBlue, dAlpha;
  1038.                     long min,max;
  1039.                     Matrix *m;
  1040.  
  1041.                     mat = *(matrix) * f->matrix;
  1042.                     // Compute inverted matrix
  1043.                     f->gradient.imat = mat.invert();
  1044.  
  1045.                     /* renormalize the matrix */
  1046.                     m=&f->gradient.imat;
  1047.                     if (f->type == f_LinearGradient) {
  1048.                         m->a = m->a * FRAC * (1/128.0) * 65536.0;
  1049.                         m->b = m->b * FRAC * (1/128.0) * 65536.0;
  1050.                         m->tx = (long) ((m->tx + 16384) * (1/128.0) * 65536.0);
  1051.                     } else {
  1052.                         m->a = m->a * FRAC * (1/64.0) * 65536.0;
  1053.                         m->b = m->b * FRAC * (1/64.0) * 65536.0;
  1054.                         m->c = m->c * FRAC * (1/64.0) * 65536.0;
  1055.                         m->d = m->d * FRAC * (1/64.0) * 65536.0;
  1056.                         m->tx = (long) (m->tx * (1/64.0) * 65536.0);
  1057.                         m->ty = (long) (m->ty * (1/64.0) * 65536.0);
  1058.                     }
  1059.  
  1060.                     // Reset translation in inverted matrix
  1061.                     f->gradient.has_alpha = 0;
  1062.  
  1063.                     // Build a 256 color ramp
  1064.                     f->gradient.ramp = new Color[256];
  1065.             if (f->gradient.ramp == NULL) {
  1066.                 // Invalidate fill style
  1067.             f->type = f_None;
  1068.             continue;
  1069.             }
  1070.  
  1071.                     // Store min and max
  1072.                     min = f->gradient.ratio[0];
  1073.                     max = f->gradient.ratio[f->gradient.nbGradients-1];
  1074.                     for(r=0; r < f->gradient.nbGradients-1; r++)
  1075.                     {
  1076.                         Color start,end;
  1077.  
  1078.                         l = f->gradient.ratio[r+1]-f->gradient.ratio[r];
  1079.                         if (l == 0) continue;
  1080.  
  1081.                         if (cxform) {
  1082.                             start = cxform->getColor(f->gradient.color[r]);
  1083.                             end   = cxform->getColor(f->gradient.color[r+1]);
  1084.                         } else {
  1085.                             start = f->gradient.color[r];
  1086.                             end   = f->gradient.color[r+1];
  1087.                         }
  1088.                         
  1089.                         if (start.alpha != ALPHA_OPAQUE || 
  1090.                             end.alpha != ALPHA_OPAQUE) {
  1091.                             f->gradient.has_alpha = 1;
  1092.                         }
  1093.  
  1094.                         dRed   = end.red - start.red;
  1095.                         dGreen = end.green - start.green;
  1096.                         dBlue  = end.blue - start.blue;
  1097.                         dAlpha = end.alpha - start.alpha;
  1098.                         
  1099.                         dRed   = (dRed<<16)/l;
  1100.                         dGreen = (dGreen<<16)/l;
  1101.                         dBlue  = (dBlue<<16)/l;
  1102.                         dAlpha  = (dAlpha<<16)/l;
  1103.  
  1104.                         red   = start.red <<16;
  1105.                         green = start.green <<16;
  1106.                         blue  = start.blue <<16;
  1107.                         alpha  = start.alpha <<16;
  1108.  
  1109.                         for (n=f->gradient.ratio[r]; n<=f->gradient.ratio[r+1]; n++) {
  1110.                             f->gradient.ramp[n].red = red>>16;
  1111.                             f->gradient.ramp[n].green = green>>16;
  1112.                             f->gradient.ramp[n].blue = blue>>16;
  1113.                             f->gradient.ramp[n].alpha = alpha>>16;
  1114.  
  1115.                             f->gradient.ramp[n].pixel = gd->allocColor(f->gradient.ramp[n]);
  1116.                             red += dRed;
  1117.                             green += dGreen;
  1118.                             blue += dBlue;
  1119.                             alpha += dAlpha;
  1120.                         }
  1121.                     }
  1122.                     for(n=0; n<min; n++) {
  1123.                         f->gradient.ramp[n] = f->gradient.ramp[min];
  1124.                     }
  1125.                     for(n=max; n<256; n++) {
  1126.                         f->gradient.ramp[n] = f->gradient.ramp[max];
  1127.                     }
  1128.                 }
  1129.                 break;
  1130.             case f_TiledBitmap:
  1131.             case f_clippedBitmap:
  1132.                 if (f->bitmap) {
  1133.                     Matrix *m;
  1134.  
  1135.                     f->cmap = gd->getColormap(f->bitmap->colormap, 
  1136.                                               f->bitmap->nbColors, cxform);
  1137.             if (f->cmap == NULL) {
  1138.             /* Get the normal cmap anyway */
  1139.                 f->cmap = f->bitmap->colormap;
  1140.             }
  1141.  
  1142.                     f->bitmap_matrix = *(matrix) * f->matrix;
  1143.  
  1144.                     f->bitmap_matrix = f->bitmap_matrix.invert();
  1145.  
  1146.                     m=&f->bitmap_matrix;
  1147.                     m->a = m->a * FRAC * 65536.0;
  1148.                     m->b = m->b * FRAC * 65536.0;
  1149.                     m->c = m->c * FRAC * 65536.0;
  1150.                     m->d = m->d * FRAC * 65536.0;
  1151.                     m->tx = (long) (m->tx * 65536.0);
  1152.                     m->ty = (long) (m->ty * 65536.0);
  1153.  
  1154.                     f->alpha_table = NULL;
  1155.  
  1156.                     if (f->bitmap->alpha_buf && cxform) {
  1157.                         unsigned char *alpha_table;
  1158.                         int i;
  1159.  
  1160.                         alpha_table = (unsigned char *)malloc (256);
  1161.                         if (alpha_table != NULL) {
  1162.                             for(i=0;i<256;i++) {
  1163.                                 alpha_table[i] = cxform->getAlpha(i);
  1164.                             }
  1165.                         }
  1166.                         f->alpha_table = alpha_table;
  1167.                     }
  1168.                 }
  1169.                 break;
  1170.         }
  1171.     }
  1172. }
  1173.  
  1174. static void
  1175. clearStyles(GraphicDevice *gd, FillStyleDef *ftab, long n)
  1176. {
  1177.     long fs;
  1178.     FillStyleDef *f;
  1179.  
  1180.     for(fs = 0; fs < n; fs++)
  1181.     {
  1182.         f = ftab + fs;
  1183.         switch (f->type)
  1184.         {
  1185.             case f_Solid:
  1186.                 break;
  1187.             case f_LinearGradient:
  1188.             case f_RadialGradient:
  1189.                 if (f->gradient.ramp) {
  1190.                     delete f->gradient.ramp;
  1191.                 }
  1192.                 break;
  1193.             case f_TiledBitmap:
  1194.             case f_clippedBitmap:
  1195.                 if (f->bitmap) {
  1196.                     if (f->cmap && f->cmap != f->bitmap->colormap) delete f->cmap;
  1197.                     if (f->alpha_table) free(f->alpha_table);
  1198.                 }
  1199.                 break;
  1200.         case f_None:
  1201.             break;
  1202.         }
  1203.     }
  1204. }
  1205.  
  1206.